package Hxw3DEngine.core.component.animation
{
	import Hxw3DEngine.core.component.Skeleton;
	import Hxw3DEngine.core.display.GameObject;
	import Hxw3DEngine.core.component.renderer.SkinnedMeshRenderer;
	import Hxw3DEngine.core.Resource.animation.SkeletonAnimationClip;
	import ao3s2.Flash3dLib.CModule;
	
	//骨骼动画管理器
	public class SkeletonAnimation extends Animation
	{
		private var _skeleton:Skeleton;
		private var _jointPoseMatrices:int;	// 骨骼动画产生的世界矩阵。
		private var _jointPoseDatas:int;  	// 与初始骨骼逆矩阵抵消过的矩阵
		
		public function SkeletonAnimation()
		{
			super();
		}
		
		override public function onAdd(master:GameObject):void
		{
			super.onAdd(master);
			_skeleton = _object3d.getComponent(Skeleton) as Skeleton;
			_jointPoseMatrices = CModule.malloc(_skeleton.skeletonResource.numberOfJoints * 48);
			_jointPoseDatas = CModule.malloc(_skeleton.skeletonResource.numberOfJoints * 32);
		}
		
		override public function dispose(force:Boolean = false):void
		{
			super.dispose(force);
			CModule.free(_jointPoseMatrices);
			_jointPoseMatrices = 0;
			CModule.free(_jointPoseDatas);
			_jointPoseDatas = 0;
		}
		
		override public function run():void
		{
			var meshRenderer:SkinnedMeshRenderer = _object3d.getComponent(SkinnedMeshRenderer) as SkinnedMeshRenderer;
			if (meshRenderer != null)
			{
				var clip:SkeletonAnimationClip = SkeletonAnimationClip(currentAnimation);
				
				var clipCacheSet:SkeletonClipCacheSet = SkeletonClipCacheSet.getInstance(_skeleton.skeletonResource);
				var clipCache:SkeletonClipCache = clipCacheSet ? clipCacheSet.getClipCache(clip.name, clip) : null;
				if (!clipCache || !clipCache.getCachedFrame(currentFrame, _jointPoseDatas, _jointPoseMatrices))
				{
					
					Flash3dLib.updatePoseMatricesAndSkinDatas(
						_jointPoseMatrices, 
						_jointPoseDatas, 
						clip.tracks, 
						_skeleton.skeletonResource.parents, 
						_skeleton.skeletonResource.bind_mtx, 
						currentFrame, 
						_skeleton.skeletonResource.numberOfJoints, 
						1);
					if (clipCache)
					{
						clipCache.cacheFrame(currentFrame, _jointPoseDatas, _jointPoseMatrices);
					}
				}
			}
		}
		
		public function get jointPoseDatas():int
		{
			return _jointPoseDatas;
		}
		
		public function get dualQuat():Boolean
		{
			return true;
		}
	
	}
}